<#assign object = doc.object>
package ${object.package}.gwt.client;

import java.util.Iterator;
import java.util.Set;
<#if object.trashcan[0]?? && object.trashcan == "true">
import java.util.ArrayList;
import java.util.List;
</#if>

import ${object.package}.gwt.client.constants.Constants;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
<#if object.attributes.date[0]?? || object.attributes.datetime[0]??>
import java.util.Date;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.datepicker.client.DatePicker;
</#if>
import com.google.gwt.libideas.validation.client.ValidatorController;
import redora.rdo.client.validation.NotNullValidator;
import redora.rdo.client.validation.RegExpValidator;
import redora.rdo.client.validation.NumCheckValidator;
import com.google.gwt.gen2.table.client.FixedWidthFlexTable;
import com.google.gwt.gen2.table.client.FixedWidthGrid;
import com.google.gwt.gen2.table.client.ScrollTable;
import com.google.gwt.gen2.table.client.SelectionGrid.SelectionPolicy;
import com.google.gwt.gen2.table.override.client.FlexTable.FlexCellFormatter;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
<#if object.attributes.enum[0]?? || object.attributes.object[0]??>
import com.google.gwt.user.client.ui.ListBox;
</#if>
import com.google.gwt.user.client.ui.LazyPanel;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.TextBox;
<#if object.attributes.html[0]??>
import com.google.gwt.user.client.ui.RichTextArea;
</#if>
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.Hyperlink;

public class ${object.name}ViewPanel extends LazyPanel {

	private ScrollTable scrollTable = null;

	Constants constants = GWT.create(Constants.class);
	
	private String baseUrl = GWT.getModuleBaseURL() + "${object.name?uncap_first}Operations.do?";
	
	FlowPanel root = new FlowPanel();
	
	<#if object.attributes.date[0]??>
	private final String DATE = "yyyy-MM-dd";
	</#if>
	
	<#if object.attributes.datetime[0]??>
	private final String DATETIME = "yyyy-MM-dd HH:mm:ss";
	</#if>
	
	<#if object.trashcan[0]?? && object.trashcan == "true">
	List<Long> idList = new ArrayList<Long>();
	</#if>
	
	public final String BLANK = "&nbsp;";

	public ${object.name}ViewPanel() {
	}
	
	public Widget createWidget() {
		// Combine the components into a ScrollTable
		final ScrollTable scrollTable = createScrollTable();

		createDataList();

		HorizontalPanel panel = new HorizontalPanel();

		panel.setWidth("100%");

		final FlexTable table = new FlexTable();
		table.setWidth("500");

		Hyperlink add = new Hyperlink();
		add.setText("New");
		//Button add = new Button("New");
		//add.setWidth("150");
		add.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				DialogBox dialogBox = createDialogBox(true);
				dialogBox.setGlassEnabled(true);
				dialogBox.setAnimationEnabled(true);
				dialogBox.center();
				dialogBox.show();
			}

		});
		
		Hyperlink delete = new Hyperlink();
		delete.setText("Delete");
		//Button delete = new Button("Delete");
		//delete.setWidth("150");
		delete.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				if (scrollTable.getDataTable().getSelectedRows().size() < 1) {
					Window.alert("You must select a record first!");
					return;
				}
				Set<Integer> set = scrollTable.getDataTable().getSelectedRows();
				Iterator<Integer> it = set.iterator();
				while (it.hasNext()) {
					final int row = it.next();
					String id = scrollTable.getDataTable().getText(row, 0);
					String _url = URL.encode(baseUrl + "_operationType=remove&id=" + id);
					RequestBuilder builder = new RequestBuilder(
							RequestBuilder.GET, _url);
					builder.setCallback(new RequestCallback() {
						public void onError(Request request, Throwable exception) {
							Window.alert("Delete failed!");
						}

						public void onResponseReceived(Request request,
								Response response) {
							JSONObject object = JSONParser
								.parse(response.getText()).isObject().get(
										"response").isObject();
							if (object.get("status").toString().equalsIgnoreCase("-1")) {
								Window.alert(object.get("error").toString());
								return;
							}
							if (object.get("status").toString().equalsIgnoreCase("-2")) {
								Window.alert(object.get("error").toString());
								return;
							}
							//scrollTable.getDataTable().removeRow(row);
							scrollTable.getDataTable().clearAll();
							createDataList();
						}
					});
					try {
						builder.send();
					} catch (RequestException e) {
						e.printStackTrace();
					}
				}

			}
		});
		
		<#if object.trashcan[0]?? && object.trashcan == "true">
		final Hyperlink undo = new Hyperlink();
		undo.setText("Undo");
		undo.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				for (int i = 0; i < idList.size(); i++) {
					Long id = idList.get(i);
					String _url = URL.encode(baseUrl
							+ "_operationType=undo&id=" + id);
					RequestBuilder builder = new RequestBuilder(
							RequestBuilder.GET, _url);
					builder.setCallback(new RequestCallback() {
						public void onError(Request request, Throwable exception) {
							Window.alert("Undo failed!");
						}

						public void onResponseReceived(Request request,
								Response response) {
							JSONObject object = JSONParser.parse(
									response.getText()).isObject().get(
									"response").isObject();
							if (object.get("status").toString()
									.equalsIgnoreCase("-1")) {
								Window.alert(object.get("error").toString());
								return;
							}
							if (object.get("status").toString()
									.equalsIgnoreCase("-2")) {
								Window.alert(object.get("error").toString());
								return;
							}
							scrollTable.getDataTable().clearAll();
							createDataList();
							undo.setVisible(false);
						}
					});
					try {
						builder.send();
					} catch (RequestException e) {
						e.printStackTrace();
					}
				}
			}

		});
		
		Hyperlink trash = new Hyperlink();
		trash.setText("Trash");
		trash.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				if (scrollTable.getDataTable().getSelectedRows().size() < 1) {
					Window.alert("You must select a record first!");
					return;
				}
				Set<Integer> set = scrollTable.getDataTable().getSelectedRows();
				Iterator<Integer> it = set.iterator();
				idList.clear();
				while (it.hasNext()) {
					final int row = it.next();
					idList.add(Long.valueOf(scrollTable.getDataTable().getText(
							row, 0)));
					String id = scrollTable.getDataTable().getText(row, 0);
					String _url = URL.encode(baseUrl + "_operationType=trash&id=" + id);
					RequestBuilder builder = new RequestBuilder(
							RequestBuilder.GET, _url);
					builder.setCallback(new RequestCallback() {
						public void onError(Request request, Throwable exception) {
							Window.alert("Trash failed!");
						}

						public void onResponseReceived(Request request,
								Response response) {
							JSONObject object = JSONParser
								.parse(response.getText()).isObject().get(
										"response").isObject();
							if (object.get("status").toString().equalsIgnoreCase("-1")) {
								Window.alert(object.get("error").toString());
								return;
							}
							if (object.get("status").toString().equalsIgnoreCase("-2")) {
								Window.alert(object.get("error").toString());
								return;
							}
							//scrollTable.getDataTable().removeRow(row);
							undo.setVisible(true);
							scrollTable.getDataTable().clearAll();
							createDataList();
							
						}
					});
					try {
						builder.send();
					} catch (RequestException e) {
						e.printStackTrace();
					}
				}
			}

		});
		</#if>
		
		Hyperlink refresh = new Hyperlink();
		refresh.setText("Refresh");
		refresh.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				scrollTable.getDataTable().clearAll();
				createDataList();
				scrollTable.getDataTable().deselectAllRows();
				<#if object.trashcan[0]?? && object.trashcan == "true">
				undo.setVisible(false);
				</#if>
			}

		});
		
		table.setWidget(0, 0, add);
		<#if object.trashcan[0]?? && object.trashcan == "true">
		table.setWidget(0, 1, trash);
		table.setWidget(0, 3, undo);
		undo.setVisible(false);
		<#else>
		table.setWidget(0, 1, delete);
		</#if>
		table.setWidget(0, 2, refresh);
		panel.add(table);

		// Add the components to the page
		root.add(scrollTable);
		root.add(panel);
		return root;
	}
	
	/**
	 * Create the dialog box for this add form.
	 * 
	 * @return the new dialog box
	 */
	private DialogBox createDialogBox(boolean isNew) {
		// Create a dialog box and set the caption text
		final DialogBox dialogBox = new DialogBox();
		dialogBox.setText("Add Or Update ${object.name} Form");

		FlexTable form = new FlexTable();
		form.setCellSpacing(6);
		
		final TextBox id = new TextBox();
		id.setReadOnly(true);
		form.setHTML(1, 0, "Id:");
		form.setWidget(1, 1, id);
		<#assign position = 1>
		<#list object.formScope?children as att>
			<#if att?node_name != "object" && att?node_type == "element">
				<#if att?node_name == "xml">
		final TextBox ${att.@fieldName} = new TextBox();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@fieldName}_form() + ":");
		form.setWidget(${position}, 1, ${att.@fieldName});
		${att.@fieldName}.setTitle("${att.@fieldName}");
			  	<#elseif att?node_name == "date" || att?node_name == "datetime">
				<#assign position = position + 1>
		final TextBox ${att.@name} = new TextBox();
		${att.@name}.setTitle("${att.@name}");
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@name}_form() + ":");
		form.setWidget(${position}, 1, ${att.@name});
		${att.@name}.setReadOnly(true);
		DatePicker ${att.@name}DatePicker = new DatePicker();
		${att.@name}DatePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {

			public void onValueChange(ValueChangeEvent<Date> arg0) {
				Date date = arg0.getValue();
				<#if att?node_name == "date">
				String dateString = DateTimeFormat.getFormat(DATE)
						.format(date);
				<#elseif att?node_name == "datetime">
				String dateString = DateTimeFormat.getFormat(DATETIME)
						.format(date);
				<#else>
				</#if>
				${att.@name}.setValue(dateString);
			}

		});
		form.setWidget(${position}, 2, ${att.@name}DatePicker);
					<#if att.@notnull[0]?? && att.@notnull[0] == "true">
		NotNullValidator ${att.@name}CheckNullValidation = new NotNullValidator();
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}CheckNullValidation);
					</#if> 
					<#if att.@regexp[0]??>
		RegExpValidator ${att.@name}CheckRegexpValidation = new RegExpValidator("${att.@regexp}");
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}CheckRegexpValidation);
					</#if>
			  	<#elseif att?node_name == "enum">
			  	<#assign position = position + 1>
		final ListBox ${att.@class?uncap_first} = new ListBox();
					<#list att.element as value>
		${att.@class?uncap_first}.addItem(constants.${object.name?uncap_first}_${att.@class}_${value.@name}_form(),"${value.@name}");
					</#list>
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@class}_form() + ":");
		form.setWidget(${position}, 1, ${att.@class?uncap_first});
			  	<#elseif att?node_name == "html">
				<#assign position = position + 1>
		final RichTextArea ${att.@name} = new RichTextArea();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@name}_form() + ":");
		form.setWidget(${position}, 1, ${att.@name});
		${att.@name}.setTitle("${att.@name}");
					<#if att.@notnull[0]?? && att.@notnull[0] == "true">
		NotNullValidator ${att.@name}Validation = new NotNullValidator();
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}Validation);
					</#if>
					<#if att.@regexp[0]??>
		RegExpValidator ${att.@name}CheckRegexpValidation = new RegExpValidator("${att.@regexp}");
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}CheckRegexpValidation);
					</#if>
				<#elseif att?node_name == "string">
				<#assign position = position + 1>
		final TextBox ${att.@name} = new TextBox();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@name}_form() + ":");
		form.setWidget(${position}, 1, ${att.@name});
		${att.@name}.setTitle("${att.@name}");
					<#if att.@notnull[0]?? && att.@notnull[0] == "true">
		NotNullValidator ${att.@name}Validation = new NotNullValidator();
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}Validation);
					</#if>
					<#if att.@regexp[0]??>
		RegExpValidator ${att.@name}CheckRegexpValidation = new RegExpValidator("${att.@regexp}");
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}CheckRegexpValidation);
					</#if>
				<#elseif att?node_name == "boolean">
				<#assign position = position + 1>
		final CheckBox ${att.@name} = new CheckBox();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@name}_form() + ":");
		form.setWidget(${position}, 1, ${att.@name});
		${att.@name}.setTitle("${att.@name}");
				<#elseif att?node_name == "integer">
				<#assign position = position + 1>
		final TextBox ${att.@name} = new TextBox();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@name}_form() + ":");
		form.setWidget(${position}, 1, ${att.@name});
		${att.@name}.setTitle("${att.@name}");
					<#if att.@notnull[0]?? && att.@notnull[0] == "true">
		NotNullValidator ${att.@name}Validation = new NotNullValidator();
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}Validation);
					</#if>
		NumCheckValidator ${att.@name}NumCheckValidator = new NumCheckValidator();
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}NumCheckValidator);
				<#elseif att?node_name == "long">
				<#assign position = position + 1>
					<#if att.@parentClass[0]??>
		final ListBox ${att.@parentClass?uncap_first} = new ListBox();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@parentClass}_form() + ":");
		form.setWidget(${position}, 1, ${att.@parentClass?uncap_first});
		${att.@parentClass?uncap_first}.setTitle("${att.@parentClass}");
		${att.@parentClass?uncap_first}.addItem("","");
		get${att.@parentClass}List(${att.@parentClass?uncap_first});
					<#else>	
		final TextBox ${att.@name} = new TextBox();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@name}_form() + ":");
		form.setWidget(${position}, 1, ${att.@name});
		${att.@name}.setTitle("${att.@name}");
						<#if att.@notnull[0]?? && att.@notnull[0] == "true">
		NotNullValidator ${att.@name}Validation = new NotNullValidator();
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}Validation);
						</#if>	
		NumCheckValidator ${att.@name}NumCheckValidator = new NumCheckValidator();
		ValidatorController.addAsFocusListener(${att.@name}, ${att.@name}NumCheckValidator);
					</#if> 
				<#elseif att?node_name == "double">
				<#assign position = position + 1>
		final TextBox ${att.@name} = new TextBox();
		form.setHTML(${position}, 0, constants.${object.name?uncap_first}_${att.@name}_form() + ":");
		form.setWidget(${position}, 1, ${att.@name});
		${att.@name}.setTitle("${att.@name}");   
				<#else>
		ERROR, undefined node ${att?node_name}
				</#if>
			</#if>
		</#list>
		if (!isNew) { 
			Set<Integer> set = scrollTable.getDataTable().getSelectedRows();
			Iterator<Integer> it = set.iterator();
			int row = it.next();
			id.setValue(scrollTable.getDataTable().getText(row,0));
			<#assign position = 0>
			<#list object.tableScope?children as att>
				<#if att?node_type == "element">
					<#if att?node_name == "xml">
				  	<#elseif att?node_name == "date" || att?node_name == "datetime">
					<#assign position = position + 1>
			if(!BLANK.equalsIgnoreCase(scrollTable.getDataTable().getHTML(row,${position})))
				${att.@name}.setValue(scrollTable.getDataTable().getText(row,${position}));
					<#elseif att?node_name == "enum">
			  		<#assign position = position + 1>
			for (int i = 0; i < ${att.@class?uncap_first}.getItemCount(); i++) {
				if (${att.@class?uncap_first}.getValue(i).equalsIgnoreCase(scrollTable.getDataTable().getText(row,${position})))
					${att.@class?uncap_first}.setSelectedIndex(i);
			}
			  		<#elseif att?node_name == "object">
					<#assign position = position + 1>
			if(!BLANK.equalsIgnoreCase(scrollTable.getDataTable().getHTML(row,${position})))
				${att.@class?uncap_first}Id.setValue(scrollTable.getDataTable().getText(row,${position}));
			  		<#elseif att?node_name == "html" || att?node_name == "string">
			  		<#assign position = position + 1>
			if(!BLANK.equalsIgnoreCase(scrollTable.getDataTable().getHTML(row,${position})))
				${att.@name}.setValue(scrollTable.getDataTable().getText(row,${position}));
			  		<#elseif att?node_name == "boolean">
			  		<#assign position = position + 1>
			CheckBox ${att.@name}TempCheckbox = (CheckBox) scrollTable.getDataTable().getWidget(row,${position});
			${att.@name}.setValue(${att.@name}TempCheckbox.getValue());
					<#elseif att?node_name == "integer">
					<#assign position = position + 1>
			if(!BLANK.equalsIgnoreCase(scrollTable.getDataTable().getHTML(row,${position})))
				${att.@name}.setValue(scrollTable.getDataTable().getText(row,${position}));
					<#elseif att?node_name == "long">
					<#assign position = position + 1>
			if(!BLANK.equalsIgnoreCase(scrollTable.getDataTable().getHTML(row,${position}))) {
						<#if att.@parentClass[0]??>
				for (int i = 0; i < ${att.@parentClass?uncap_first}.getItemCount(); i++) {
					if (${att.@parentClass?uncap_first}.getValue(i).equalsIgnoreCase(scrollTable.getDataTable().getHTML(row,${position})))
						${att.@parentClass?uncap_first}.setSelectedIndex(i);
				}
						<#else>
				${att.@name}.setValue(scrollTable.getDataTable().getText(row,${position}));
						</#if>
			}
					<#elseif att?node_name == "double">
					<#assign position = position + 1>
			if(!BLANK.equalsIgnoreCase(scrollTable.getDataTable().getHTML(row,${position})))
				${att.@name}.setValue(scrollTable.getDataTable().getText(row,${position}));
					<#elseif att?node_name == "set">
					<#assign position = position + 1>
					<#else>
			ERROR, undefined node ${att?node_name}
					</#if>
				</#if>
			</#list>
			<#if object.lazyScope[0]??>
			String _url = URL.encode(baseUrl + "_operationType=fetchLazy&id=" + scrollTable.getDataTable().getText(row,0));
			RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, _url);
			builder.setCallback(new RequestCallback() {
				public void onError(Request request, Throwable exception) {
					Window.alert("fetch lazy field failed!");
				}
	
				public void onResponseReceived(Request request, Response response) {
					JSONObject object = JSONParser.parse(response.getText())
							.isObject();
					JSONObject json = object.get("response").isObject().get(
							"data").isObject();
					id.setValue(json.get("id").toString());
					<#list object.lazyScope?children as att>
						<#if att?node_name != "object" && att?node_type == "element">
					if (json.get("${att.@fieldName}") != null && !"null".equalsIgnoreCase(json.get("${att.@fieldName}").toString())) {
							<#if att?node_name == "xml">
						${att.@fieldName}.setText(json.get("${att.@fieldName}").isString().stringValue());;
					  		<#elseif att?node_name == "html" || att?node_name == "string">
						${att.@fieldName}.setText(json.get("${att.@fieldName}").isString().stringValue());
							<#else>
						ERROR, undefined node ${att?node_name}
							</#if>
					}
						</#if>
					</#list>
				}
			});
			try {
				builder.send();
			} catch (RequestException e) {
				e.printStackTrace();
			}
			</#if>
		}
		
		VerticalPanel dialogContents = new VerticalPanel();
		dialogContents.setSpacing(4);
		dialogBox.setWidget(dialogContents);

		dialogContents.add(form);
		
		// Add a submit button at the bottom of the dialog
		Button submitButton = new Button("submit", new ClickHandler() {
			public void onClick(ClickEvent event) {
				String _url = URL.encode(baseUrl);
				String requestData = "_operationType=persist";
				if (id.getValue() != null && id.getValue().length() > 0)
					requestData = requestData + "&id=" + id.getValue();
				requestData = requestData 
					<#list object.formScope?children as att>
			  			<#if att?node_name != "object" && att?node_type == "element">
			  				<#if att?node_name == "xml">
			  				<#elseif att?node_name == "date" || att?node_name == "datetime">
			  			+ "&${att.@name}=" + ${att.@name}.getValue()
			  				<#elseif att?node_name == "enum">
			  			+ "&${att.@class?uncap_first}=" + ${att.@class?uncap_first}.getValue(${att.@class?uncap_first}.getSelectedIndex())
			  				<#elseif att?node_name == "html" || att?node_name == "string">
						+ "&${att.@name}=" + ${att.@name}.getText()
						    <#elseif att?node_name == "boolean">
						+ "&${att.@name}=" + ${att.@name}.getValue()
						    <#elseif att?node_name == "integer">
						+ "&${att.@name}=" + ${att.@name}.getValue()
						    <#elseif att?node_name == "long"> 
						   		<#if att.@parentClass[0]??>
						+ "&${att.@parentClass?uncap_first}Id=" + ${att.@parentClass?uncap_first}.getValue(${att.@parentClass?uncap_first}.getSelectedIndex())
						   		<#else>
						+ "&${att.@name}=" + ${att.@name}.getValue()
								</#if>
					    	<#elseif att?node_name == "double">
					    + "&${att.@name}=" + ${att.@name}.getValue()
						    <#else>
						ERROR, undefined node ${att?node_name}
							</#if>
						</#if>
					</#list>;
				
				RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
						_url);
				builder.setHeader("Content-Type", "application/x-www-form-urlencoded");  
				builder.setRequestData(requestData);
				builder.setCallback(new RequestCallback() {
					public void onError(Request request, Throwable exception) {
						Window.alert("add or update failed!");
					}

					public void onResponseReceived(Request request,
							Response response) {
						JSONObject object = JSONParser
								.parse(response.getText()).isObject().get(
										"response").isObject();
						if (object.get("status").toString().equalsIgnoreCase("-1")) {
							JSONArray array = object.get("error").isArray();
							Window.alert(array.toString());
							return;
						}
						if (object.get("status").toString().equalsIgnoreCase("-2")) {
							Window.alert(object.get("error").toString());
							return;
						} 
						scrollTable.getDataTable().clearAll();
						createDataList();
						dialogBox.hide();
					}
				});
				try {
					builder.send();
				} catch (RequestException e) {
					e.printStackTrace();
				}
			}
		});

		// Add a close button at the bottom of the dialog
		Button closeButton = new Button("close", new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});

		HorizontalPanel panel = new HorizontalPanel();
		panel.add(submitButton);
		panel.add(closeButton);

		dialogContents.add(panel);

		// Return the dialog box
		return dialogBox;
	}
	
	/**
	 * Create the scroll table.
	 * 
	 * @return a data table
	 */
	public ScrollTable createScrollTable() {
		FixedWidthFlexTable headerTable = createHeaderTable();
		FixedWidthFlexTable footerTable = createFooterTable();
		FixedWidthGrid dataTable = createDataTable();

		// Combine the components into a ScrollTable
		scrollTable = new ScrollTable(dataTable, headerTable);
		scrollTable.setFooterTable(footerTable);

		// Set some options in the scroll table
		// scrollTable.setSortingEnabled(true);
		scrollTable.setResizePolicy(ScrollTable.ResizePolicy.FILL_WIDTH);
		scrollTable.setSize("100%", "500");

		// Setup some default widths
		scrollTable.setColumnWidth(2, 50);
		scrollTable.setColumnWidth(5, 50);

		// Return the data table
		return scrollTable;
	}
	
	/**
	 * Create the data table.
	 * 
	 * @return a data table
	 */
	public FixedWidthGrid createDataTable() {
		// Create a new table
		//FixedWidthGrid dataTable = new FixedWidthGrid();
		FixedWidthGrid dataTable = new FixedWidthGrid() {
			public void onBrowserEvent(Event event) {
				this
						.sinkEvents(Event.ONBLUR | Event.ONCLICK
								| Event.ONDBLCLICK);
				DialogBox dialogBox;
				if (event.getTypeInt() == Event.ONDBLCLICK) {
					Element element = this.getEventTargetRow(event);
					this.selectRow(this.getRowIndex(element), true);
					dialogBox = createDialogBox(false);
					dialogBox.setGlassEnabled(true);
					dialogBox.setAnimationEnabled(true);
					dialogBox.center();
					dialogBox.show();
				} else if (event.getTypeInt() == Event.ONCLICK) {
					Element cellElem = this.getEventTargetCell(event);
					Element rowElem = this.getEventTargetRow(event);
					<#assign position = 0>
					<#list object.tableScope?children as att>
	  					<#if att?node_type == "element">
	  					<#assign position = position + 1>
	  					</#if>
					</#list>
					<#list object.attributes.set as att>
						<#assign position = position + 1>
					if (this.getCellIndex(rowElem, cellElem) == ${position}) {
						DialogBox list = create${att.@class}List(Long.valueOf(this
								.getText(this.getRowIndex(rowElem), 0)));
						list.setGlassEnabled(true);
						list.setAnimationEnabled(true);
						list.center();
						list.show();
					}
					</#list>
					super.onBrowserEvent(event);
				} else {
					super.onBrowserEvent(event);
				}
			}
		};
		// dataTable.setSelectionPolicy(SelectionGrid.SelectionPolicy.MULTI_ROW);

		dataTable.setSelectionPolicy(SelectionPolicy.CHECKBOX);
		
		<#assign position = 1>
		<#list object.tableScope?children as att>
	  		<#if att?node_type == "element">
	  			<#assign position = position + 1>
	  		</#if>
		</#list>
		<#list object.attributes.set as att>
			<#assign position = position + 1>	
		</#list>
		dataTable.resizeColumns(${position+2});

		// Return the data table
		return dataTable;
	}
	
	/**
	 * Get the User Data List.
	 * 
	 */
	private void createDataList() {
		final FixedWidthGrid dataTable = scrollTable.getDataTable();
		String _url = URL.encode(baseUrl + "_operationType=fetch&fetchScope=table");
		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, _url);
		builder.setCallback(new RequestCallback() {
			public void onError(Request request, Throwable exception) {
				Window.alert("createDataList failed!");
			}

			public void onResponseReceived(Request request, Response response) {
				JSONObject object = JSONParser.parse(response.getText())
						.isObject();
				//JSONObject object = new JSONObject(JSON.decode(response.getText()));
				JSONArray jsons = object.get("response").isObject().get(
						"data").isArray();
				copyValue(dataTable, jsons);
			}
		});
		try {
			builder.send();
		} catch (RequestException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Create the footer table.
	 * 
	 * @return a footer table
	 */
	public FixedWidthFlexTable createFooterTable() {
		// Create a new table
		FixedWidthFlexTable footerTable = new FixedWidthFlexTable();
		// FlexCellFormatter formatter = footerTable.getFlexCellFormatter();
		// Return the footer table
		return footerTable;
	}
	
	/**
	 * Create the header table.
	 * 
	 * @return a header table
	 */
	public FixedWidthFlexTable createHeaderTable() {
		// Create a new table
		FixedWidthFlexTable headerTable = new FixedWidthFlexTable();
		FlexCellFormatter formatter = headerTable.getFlexCellFormatter();

		// Level 1 headers
//		headerTable.setHTML(0, 0, "<b>${object.name} Data</b>");
//		formatter.setColSpan(0, 0, 9);
//		formatter.setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_CENTER);

		final CheckBox selectAll = new CheckBox();
		selectAll.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent arg0) {
				if (selectAll.getValue()) {
					scrollTable.getDataTable().selectAllRows();
				} else {
					scrollTable.getDataTable().deselectAllRows();
				}
			}

		});
		headerTable.setWidget(0, 0, selectAll);
		formatter.setHorizontalAlignment(0, 0,
				HasHorizontalAlignment.ALIGN_CENTER);
		headerTable.setHTML(0, 1, "Id");
		formatter.setHorizontalAlignment(0, 1,
				HasHorizontalAlignment.ALIGN_CENTER);
				
		<#assign position = 1>
		<#list object.tableScope?children as att>
			<#if att?node_type == "element">
			  	<#if att?node_name == "date" || att?node_name == "datetime">
				<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@name}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);
			  	<#elseif att?node_name == "enum">
			  	<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@class}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);
			  	<#elseif att?node_name == "object">
			  	<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@class}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);
			  	<#elseif att?node_name == "html" || att?node_name == "string">
				<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@name}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);
				<#elseif att?node_name == "boolean">
				<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@name}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);		   
				<#elseif att?node_name == "integer">
				<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@name}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);	    
				<#elseif att?node_name == "long">
				<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@name}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);	    
				<#elseif att?node_name == "double">
				<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@name}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);
				<#else>
		ERROR, undefined node ${att?node_name}
				</#if>
			</#if>
		</#list>
		<#list object.attributes.set as att>
			<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, constants.${object.name?uncap_first}_${att.@plural}_table());
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);
		</#list>
		<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, "creationDate");
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);
		<#assign position = position + 1>
		headerTable.setHTML(0, ${position}, "updateDate");
		formatter.setHorizontalAlignment(1, ${position},HasHorizontalAlignment.ALIGN_CENTER);		

		// Return the header table
		return headerTable;
	}
	
	public void copyValue(FixedWidthGrid dataTable, JSONArray array) {
		dataTable.resizeRows(array.size());
		for (int i = 0; i < array.size(); i++) {
			JSONObject value = array.get(i).isObject();
			if (value.get("id") != null
					&& !value.get("id").toString().equalsIgnoreCase("null")) {
				dataTable.setText(i, 0, value.get("id").toString());
			}
			<#assign position = 0>
			<#list object.tableScope?children as att>
	  			<#if att?node_type == "element">
	  				<#if att?node_name == "xml">
	  				<#elseif att?node_name == "date" || att?node_name == "datetime">
	  				<#assign position = position + 1>
			if (value.get("${att.@name}") != null
					&& !value.get("${att.@name}").toString().equalsIgnoreCase(
							"null") && value.get("${att.@name}").isString().stringValue().length() > 0)
				dataTable.setText(i, ${position}, value.get("${att.@name}").isString()
						.stringValue());
					<#elseif att?node_name == "enum">	
					<#assign position = position + 1>
			if (value.get("${att.@class?uncap_first}") != null
					&& !value.get("${att.@class?uncap_first}").toString().equalsIgnoreCase(
							"null") && value.get("${att.@class?uncap_first}").isString().stringValue().length() > 0)
				dataTable.setText(i, ${position}, value.get("${att.@class?uncap_first}").isString()
						.stringValue());
	  				<#elseif att?node_name == "html" || att?node_name == "string">
	  				<#assign position = position + 1>
			if (value.get("${att.@name}") != null
					&& !value.get("${att.@name}").toString().equalsIgnoreCase(
							"null") && value.get("${att.@name}").isString().stringValue().length() > 0)
				dataTable.setText(i, ${position}, value.get("${att.@name}").isString()
						.stringValue());
	  				<#elseif att?node_name == "boolean">
	  				<#assign position = position + 1>
			if (value.get("${att.@name}") != null
					&& !value.get("${att.@name}").toString().equalsIgnoreCase(
							"null")) {
				CheckBox box = new CheckBox();
				box.setValue(Boolean.valueOf(value.get("${att.@name}").toString()));
				box.setEnabled(false);
				dataTable.setWidget(i, ${position}, box);
			}
	  				<#elseif att?node_name == "integer">
	  				<#assign position = position + 1>
			if (value.get("${att.@name}") != null
					&& !value.get("${att.@name}").toString().equalsIgnoreCase(
							"null"))
				dataTable.setText(i, ${position}, value.get("${att.@name}").toString());
	  				<#elseif att?node_name == "long">
	  				<#assign position = position + 1>
			if (value.get("${att.@name}") != null
					&& !value.get("${att.@name}").toString().equalsIgnoreCase(
							"null"))
				dataTable.setText(i, ${position}, value.get("${att.@name}").toString());
					<#elseif att?node_name == "double">
	  				<#assign position = position + 1>
			if (value.get("${att.@name}") != null
					&& !value.get("${att.@name}").toString().equalsIgnoreCase(
							"null"))
				dataTable.setText(i, ${position}, value.get("${att.@name}").toString());
					<#else>
			ERROR, undefined node ${att?node_name}
					</#if>
	  			</#if>
			</#list>
			<#list object.attributes.set as att>
			<#assign position = position + 1>
			dataTable.setText(i, ${position}, "?");	
			</#list>
			<#assign position = position + 1>
			if (value.get("creationDate") != null
					&& !value.get("creationDate").toString().equalsIgnoreCase(
							"null"))
				dataTable.setText(i, ${position}, value.get("creationDate").isString()
						.stringValue());
			<#assign position = position + 1>
			if (value.get("updateDate") != null
					&& !value.get("updateDate").toString().equalsIgnoreCase(
							"null")  && value.get("updateDate").isString().stringValue().length() > 0)
				dataTable.setText(i, ${position}, value.get("updateDate").isString()
						.stringValue());
			
				
		}
	}
	
	<#list object.attributes.object as att>
	private void get${att.@class}List(final ListBox ${att.@class?uncap_first}){
		String _url = URL.encode(GWT.getModuleBaseURL() + "${att.@class?uncap_first}Operations.do?" + "_operationType=fetch&fetchScope=list");
		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, _url);
		builder.setCallback(new RequestCallback() {
			public void onError(Request request, Throwable exception) {
				Window.alert("get${att.@class}List failed!");
			}

			public void onResponseReceived(Request request, Response response) {
				JSONObject object = JSONParser.parse(response.getText())
						.isObject();
				JSONArray jsons = object.get("response").isObject().get(
						"data").isArray();
				for(int i = 0; i< jsons.size();i++){
					Set<String> keys = jsons.get(i).isObject().keySet();
					Iterator<String> it = keys.iterator();
					StringBuffer s = new StringBuffer();
					while(it.hasNext()){
						String key = it.next();
						s.append(key + ":").append(jsons.get(i).isObject().get(key).toString());
						if(it.hasNext())
							s.append(",");
					}
					${att.@class?uncap_first}.addItem(s.toString(),jsons.get(i).isObject().get("id").toString());
				}
			}
		});
		try {
			builder.send();
		} catch (RequestException e) {
			e.printStackTrace();
		}
	}
	</#list>
	
	<#list object.attributes.set as att>
	private DialogBox create${att.@class}List(Long id) {
		final DialogBox dialogBox = new DialogBox();
		dialogBox.setWidth("800");
		dialogBox.setHeight("250");
		dialogBox.setText("${att.@class} list");
		VerticalPanel dialogContents = new VerticalPanel();
		dialogContents.setSpacing(4);
		dialogBox.setWidget(dialogContents);

		final ${att.@class}ViewPanel panel = new ${att.@class}ViewPanel();

		FixedWidthFlexTable headerTable = panel.createHeaderTable();
		FixedWidthFlexTable footerTable = panel.createFooterTable();
		final FixedWidthGrid dataTable = panel.createDataTable();
		dataTable.unsinkEvents(Event.ONBLUR | Event.ONCLICK | Event.ONDBLCLICK);

		// Combine the components into a ScrollTable
		ScrollTable ${att.@class?uncap_first}scrollTable = new ScrollTable(dataTable, headerTable);
		${att.@class?uncap_first}scrollTable.setFooterTable(footerTable);

		// Set some options in the scroll table
		// scrollTable.setSortingEnabled(true);
		${att.@class?uncap_first}scrollTable.setResizePolicy(ScrollTable.ResizePolicy.FILL_WIDTH);
		${att.@class?uncap_first}scrollTable.setSize("800", "200");

		// Setup some default widths
		${att.@class?uncap_first}scrollTable.setColumnWidth(2, 50);
		${att.@class?uncap_first}scrollTable.setColumnWidth(5, 50);

		String _url = URL.encode(GWT.getModuleBaseURL() + "${att.@class?uncap_first}Operations.do?"
				+ "_operationType=fetch&findByParams=true&fetchScope=table&${object.name?uncap_first}Id=" + id);
		RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, _url);
		builder.setCallback(new RequestCallback() {
			public void onError(Request request, Throwable exception) {
				Window.alert("create${att.@class}List failed!");
			}

			public void onResponseReceived(Request request, Response response) {
				JSONObject object = JSONParser.parse(response.getText())
						.isObject();
				JSONArray jsons = object.get("response").isObject().get("data")
						.isArray();
				panel.copyValue(dataTable, jsons);
			}
		});
		try {
			builder.send();
		} catch (RequestException e) {
			e.printStackTrace();
		}

		dialogContents.add(${att.@class?uncap_first}scrollTable);
		Button closeButton = new Button("close", new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});
		dialogContents.add(closeButton);
		return dialogBox;
	}
	</#list>
	
}
